/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 */

#ifndef __RT_FIFO_H__
#define __RT_FIFO_H__

#include <rtthread.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
    rt_uint8_t           *buffer_ptr;           /**< Pointer to FIFO data memory.                        */
    rt_uint32_t           buffer_size_mask;     /**< Read/write index mask. Also used for size checking. */
    volatile rt_uint32_t  read_index;           /**< Next read position in the FIFO data.                */
    volatile rt_uint32_t  write_index;          /**< Next write position in the FIFO data.               */
} rt_fifo_t;

void rt_fifo_init(rt_fifo_t *fifo, rt_uint8_t *pool, rt_uint32_t size);
rt_uint32_t rt_fifo_put(rt_fifo_t *fifo, const rt_uint8_t byte);
rt_uint32_t rt_fifo_get(rt_fifo_t *fifo, rt_uint8_t *byte);
void rt_fifo_flush(rt_fifo_t *fifo);
void rt_fifo_clear(rt_fifo_t *fifo);
rt_uint32_t rt_fifo_read(rt_fifo_t *fifo, rt_uint8_t *ptr, rt_uint32_t length);
rt_uint32_t rt_fifo_write(rt_fifo_t *fifo, const rt_uint8_t *ptr, rt_uint32_t length);
rt_uint32_t rt_fifo_get_read_ptr(rt_fifo_t *fifo, rt_uint8_t **ptr);
rt_uint32_t rt_fifo_get_write_ptr(rt_fifo_t *fifo, rt_uint8_t **ptr);
void rt_fifo_write_index_update(rt_fifo_t *fifo, rt_uint32_t idx);
void rt_fifo_read_index_update(rt_fifo_t *fifo, rt_uint32_t idx);

rt_inline rt_uint32_t rt_fifo_length(rt_fifo_t *fifo)
{
    return fifo->write_index - fifo->read_index;
}

rt_inline rt_uint32_t rt_fifo_free_length(rt_fifo_t *fifo)
{
    return (fifo->buffer_size_mask + 1) - rt_fifo_length(fifo);
}

rt_inline rt_bool_t rt_fifo_full(rt_fifo_t *fifo)
{
    return rt_fifo_length(fifo) > fifo->buffer_size_mask;
}

rt_inline rt_bool_t rt_fifo_empty(rt_fifo_t *fifo)
{
    return fifo->write_index == fifo->read_index;
}

#ifdef __cplusplus
}
#endif

#endif
